/*
 * Copyright (C) 2024 ~ 2025 Deepin Technology Co., Ltd.
 *
 * Author:     zhangbingyi <zhangbingyi@uniontech.com>
 *
 * Maintainer: zhangbingyi <zhangbingyi@uniontech.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "usbdevicedetailsdlg.h"
#include "usbstoragesecuritywidget.h"
#include "widgets/settingsgroup.h"
#include "widgets/titlebuttonitem.h"
#include "widgets/defendertable.h"
#include "widgets/settingsheaderitem.h"
#include "securitytools/usbconnection/widgets/usbinfolabel.h"
#include "securitytools/usbconnection/widgets/usbinfodialog.h"
#include "widgets/defendertableheaderview.h"

//#include <DCommandLinkButton>
//#include <DTipLabel>
//#include <DTableView>
//#include <DApplicationHelper>
//#include <DSimpleListView>
//#include <DDialog>
//#include <DFontSizeManager>
//#include <DButtonBox>
//#include <DApplicationHelper>
//#include <DSuggestButton>
//#include <DPinyin>
//#include <DWarningButton>
#include <QFileDialog>

#include <QVBoxLayout>
#include <QApplication>
#include <QMenu>
#include <QStandardItemModel>
#include <QTableView>
#include <QScrollBar>
#include <QGraphicsOpacityEffect>
#include <QDateTime>

#define ALLOW_RW_NAME "Read-write" // 允许所有菜单项名称
#define ALLOW_RO_NAME "Read only" // 仅允许白名单菜单项名称
#define BLOCK_NO_NAME "Block" // 禁止所有菜单项名称

// 限制模式菜单检索
#define LIMIT_MODE_RW_INDEX 0
#define LIMIT_MODE_RO_INDEX 1
#define LIMIT_MODE_NO_INDEX 2

// 连接记录列表 各项列数
#define USB_LOG_ITEM_NAME_COL 0 // 连接记录列表 名称项列数
#define USB_LOG_ITEM_TIME_COL 1 // 连接记录列表 时间项列数
#define USB_LOG_ITEM_STATUS_COL 2 // 连接记录列表 连接状态项列数
#define USB_LOG_ITEM_BTN_COL 3 // 连接记录列表 按钮项列数
#define USB_LOG_ITEM_DATA_COL 4 // 连接记录列表 数据项列数

// 白名单列表 各项列数
#define USB_WHITELIST_ITEM_NAME_COL 0 // 白名单列表 名称项列数
#define USB_WHITELIST_ITEM_TIME_COL 1 // 白名单列表 时间项列数
#define USB_WHITELIST_ITEM_BTN_COL 2 // 白名单列表 按钮项列数
#define USB_WHITELIST_ITEM_DATA_COL 3 // 白名单列表 数据项列数

// 数据存储偏移
#define DATA_ROLE_NAME Qt::UserRole + 1 // 数据存储偏移 - 名称
#define DATA_ROLE_TIME Qt::UserRole + 2 // 数据存储偏移 - 时间
#define DATA_ROLE_STRATEGY Qt::UserRole + 3 // 数据存储偏移 - 连接状态
#define DATA_ROLE_SERIAL Qt::UserRole + 4 // 数据存储偏移 - 序列号
#define DATA_ROLE_VENDOR_ID Qt::UserRole + 5 // 数据存储偏移 - 制造商id
#define DATA_ROLE_PRODUCT_ID Qt::UserRole + 6 // 数据存储偏移 - 生产商id
#define DATA_ROLE_OP_STATUS Qt::UserRole + 7 // 数据存储偏移 - 操作（添加/移除）白名单状态

// 白名单操作状态
#define USB_ON_WHITELIST 1 // 在白名单列表中
#define USB_NOT_ON_WHITELIST 0 // 不在白名单列表中

// 自动化标签
#define SET_ACC_NAME(control, name) SET_ACCESS_NAME(control, USBStorageSecurityWidget, name)

USBStorageSecurityWidget::USBStorageSecurityWidget(USBStorageSecurityModel *model, QWidget *parent)
    : QWidget(parent)
    , m_usbStorageSecurityModel(model)
    , m_usbLimitModeItem(nullptr)
    , m_usbLimitModeItemButtonLabel(nullptr)
    , m_usbLimitModeMenu(nullptr)
    , m_searchEdit(nullptr)
    , m_headerDelegate(nullptr)
    , m_connectionRecordTableWgt(nullptr)
    , m_connectionRecordTable(nullptr)
    , m_connectionRecordTableModel(nullptr)
    , m_whiteListBtn(nullptr)
    , m_clearLogBtn(nullptr)
    , m_exportBtn(nullptr)
    , m_whitelistDialog(nullptr)
    , m_USBDeviceDetails(nullptr)
    , m_USBRecordsDelegate(nullptr)
    , m_blankTip(nullptr)
    , m_blankArea(nullptr)
{
    SET_ACC_NAME(this, USBStorageSecurityMainWindow);

    this->setFocusPolicy(Qt::FocusPolicy::ClickFocus); // 设置可点击聚焦

    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->setAlignment(Qt::AlignLeft);
    mainLayout->setSpacing(0);
    setLayout(mainLayout);

    QLabel *titleLabel = new QLabel(tr("USB Connection"), this);
    SET_ACC_NAME(titleLabel, titleLable);
    titleLabel->setContentsMargins(0, 0, 0, 0);
    QFont font = titleLabel->font();
    font.setBold(true);
    titleLabel->setFont(font);
//    DFontSizeManager::instance()->bind(titleLabel, DFontSizeManager::T5);

    // 水平布局放置 title 以及 搜索框
    QHBoxLayout *titleBoxLayout = new QHBoxLayout;
    titleBoxLayout->addSpacing(10);
    titleBoxLayout->addWidget(titleLabel, 0, Qt::AlignLeft);
    mainLayout->addLayout(titleBoxLayout);

    // 搜索框
    m_searchEdit = new QLineEdit(this);
    SET_ACC_NAME(m_searchEdit, searchEdit);
    m_searchEdit->setToolTip(tr("Enter a name, PID, VID, or SN to search"));
//    m_searchEdit->setPlaceHolder(tr("Search"));
    m_searchEdit->setMinimumWidth(190);
    titleBoxLayout->addWidget(m_searchEdit, 0, Qt::AlignmentFlag::AlignRight | Qt::AlignmentFlag::AlignVCenter);
    titleBoxLayout->addSpacing(10);

    m_usbLimitModeItem = new TitleButtonItem(this);
    SET_ACC_NAME(m_usbLimitModeItem, usbLimitModelFrame);
    m_usbLimitModeItem->setAccessibleParentText("settingFrame");
    m_usbLimitModeItem->setParent(this);
    m_usbLimitModeItem->setTitle(tr("Connection of USB storage devices"));
    mainLayout->addSpacing(10);
    mainLayout->addWidget(m_usbLimitModeItem);

    //usbLimitModeItemButton
    m_usbLimitModeItem->button()->setMinimumWidth(130);
    QHBoxLayout *usbLimitModeItemButtonLayout = new QHBoxLayout;
    usbLimitModeItemButtonLayout->setContentsMargins(10, 0, 10, 0);
    m_usbLimitModeItem->button()->setLayout(usbLimitModeItemButtonLayout);
    m_usbLimitModeItemButtonLabel = new QLabel(this);
    SET_ACC_NAME(m_usbLimitModeItemButtonLabel, usbLimitModelLable);
    usbLimitModeItemButtonLayout->addWidget(m_usbLimitModeItemButtonLabel);
    m_usbLimitModeItemButtonLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter);

    m_usbLimitModeMenu = new QMenu(this);
    SET_ACC_NAME(m_usbLimitModeMenu, usbLimitModeMenu);
    m_usbLimitModeItem->button()->setMenu(m_usbLimitModeMenu);
    QAction *allowAllAction = new QAction(tr("Read-write"), this);
    allowAllAction->setObjectName(ALLOW_RW_NAME);
    allowAllAction->setCheckable(true);
    m_usbLimitModeMenu->addAction(allowAllAction);
    QAction *onlyWhitelistAction = new QAction(tr("Read only"), this);
    onlyWhitelistAction->setObjectName(ALLOW_RO_NAME);
    onlyWhitelistAction->setCheckable(true);
    m_usbLimitModeMenu->addAction(onlyWhitelistAction);
    QAction *blockAllAction = new QAction(tr("Block"), this);
    blockAllAction->setObjectName(BLOCK_NO_NAME);
    blockAllAction->setCheckable(true);
    m_usbLimitModeMenu->addAction(blockAllAction);

    // 初始化限制模式选项
    int mode = m_usbStorageSecurityModel->getGlobalPermMode();
    if (USB_MANAGER_PERM_MODE_RW == mode) {
        allowAllAction->setChecked(true);
        m_usbLimitModeItemButtonLabel->setText(allowAllAction->text());
    } else if (USB_MANAGER_PERM_MODE_RO == mode) {
        onlyWhitelistAction->setChecked(true);
        m_usbLimitModeItemButtonLabel->setText(onlyWhitelistAction->text());
    } else if (USB_MANAGER_PERM_MODE_NO == mode) {
        blockAllAction->setChecked(true);
        m_usbLimitModeItemButtonLabel->setText(blockAllAction->text());
    }

    // --- NEW ---

    //connectionRecordBtn and whiteListBtn
    mainLayout->addSpacing(10);
    QLabel *connectionRecord = new QLabel(tr("Connections"));
    SET_ACC_NAME(connectionRecord, connectionRecord);

    QHBoxLayout *btnBoxLayout = new QHBoxLayout; // 水平布局放置
    btnBoxLayout->addSpacing(10);
    btnBoxLayout->addWidget(connectionRecord, 0, Qt::AlignLeft);

    m_whiteListBtn = new QCommandLinkButton(tr("Whitelist"));
    btnBoxLayout->addWidget(m_whiteListBtn, 0, Qt::AlignRight);
    btnBoxLayout->addSpacing(10);

    mainLayout->addLayout(btnBoxLayout);

    // --- NEW ---
    // 无策略时文字区域
    mainLayout->addSpacing(5);
    QVBoxLayout *blankLayout = new QVBoxLayout();
    m_blankArea = new HFrame1(this);
    m_blankArea->setBackgroundType(HFrame1::ItemBackground);
    m_blankArea->setLineWidth(0);
    m_blankArea->setLayout(blankLayout);
    mainLayout->addWidget(m_blankArea, 1);

    m_blankTip = new QLabel("", this);
//    DFontSizeManager::instance()->bind(m_blankTip, DFontSizeManager::T6);
    blankLayout->addWidget(m_blankTip);

    // --- NEW ---
    //bottom line
    QHBoxLayout *bottomLayout = new QHBoxLayout;

    m_clearLogBtn = new QCommandLinkButton(tr("Clear all records"));
//    DFontSizeManager::instance()->bind(m_clearLogBtn, DFontSizeManager::T8);
    SET_ACC_NAME(m_clearLogBtn, clearButton);
    bottomLayout->addWidget(m_clearLogBtn);
    bottomLayout->addStretch(1);
    QLabel *logTableTip = new QLabel(tr("The list only displays records for 30 days. For more records, please export."));
//    DFontSizeManager::instance()->bind(logTableTip, DFontSizeManager::T8);
//    logTableTip->setElideMode(Qt::TextElideMode::ElideMiddle);
    SET_ACC_NAME(logTableTip, logTableTipLable);
    bottomLayout->addWidget(logTableTip);

    // 添加一个导出按钮
    m_exportBtn = new QCommandLinkButton(tr("Export all records"));
//    DFontSizeManager::instance()->bind(m_exportBtn, DFontSizeManager::T8);
    SET_ACC_NAME(m_exportBtn, exportButton);
    bottomLayout->addWidget(m_exportBtn);

    //添加表格模块
    mainLayout->addLayout(initTable());
    // 添加底部 清除以及导出模块
    mainLayout->addLayout(bottomLayout);

    // 根据表格内容是否为空，设置清除记录按钮是否可用
    if (0 == m_connectionRecordTableModel->rowCount()) {
        m_clearLogBtn->setDisabled(true);
    }

    // 随数据处理对象中的操作按钮状态来设置界面中按钮状态
    enableAllWidgets(m_usbStorageSecurityModel->getUIEnableStatus());

    // connect
    initConnect();

    // 隐藏遮蔽区域 显示表格
    m_blankArea->hide();
    m_connectionRecordTableWgt->show();
    m_connectionRecordTable->show();
}

USBStorageSecurityWidget::~USBStorageSecurityWidget()
{
    m_connectionRecordTableModel->clear();
    m_connectionRecordTableModel->deleteLater();
    m_connectionRecordTableModel = nullptr;
}

void USBStorageSecurityWidget::onRecvNeedShowRecords(const USBConnectionInfoList &list)
{
    // 若已经接收过初始连接记录，则不重复添加到表格
    if (0 < m_connectionRecordTableModel->rowCount()) {
        return;
    }

    for (int i = 0; i < list.size(); i++) {
        const USBConnectionInfo &info = list.at(i);
        appendUsbConnectionLog(info);
    }

    //不显示 数据 栏
    m_connectionRecordTable->setColumnHidden(USB_LOG_ITEM_DATA_COL, true);
}

void USBStorageSecurityWidget::onReceiveUsbInfo(USBConnectionInfo info)
{
    //清除超过30天记录项
    cleanUsbConnectionLog();
    appendUsbConnectionLog(info);

    //不显示 数据 栏
    m_connectionRecordTable->setColumnHidden(USB_LOG_ITEM_DATA_COL, true);
}

void USBStorageSecurityWidget::onOpenWhitelist()
{
    // 扫描白名单弹框
    m_whitelistDialog = new USBWhiteListDlg(m_usbStorageSecurityModel, this);
    m_whitelistDialog->raise();
    m_whitelistDialog->show();
}

void USBStorageSecurityWidget::onShowDetailsDlg(const USBConnectionInfo &info)
{
    // USB设备详情页弹窗
    m_USBDeviceDetails = new USBDeviceDetailsDlg(m_usbStorageSecurityModel, info, this);
    m_USBDeviceDetails->raise();
    m_USBDeviceDetails->show();
}


static int gType;
static USBConnectionInfo gInfo;
// delegate 响应移除白名单操作
void USBStorageSecurityWidget::onWhitelistStrategyChanged(int type, const USBConnectionInfo &info)
{
    // 白名单移除：弹出二次确认弹窗
    if (type == USB_MANAGER_OP_TYPE_REMOVE) {
        // 用户确认
        DDialog *dialog = new DDialog(this);
        SET_ACC_NAME(dialog, RemoveWhitelistDialog);
        dialog->setModal(true);
        dialog->setOnButtonClickedClose(true);
        // 设置关闭后删除
        dialog->setAttribute(Qt::WA_DeleteOnClose);
        // 设置左上角图标
        dialog->setIcon(QIcon::fromTheme(DIALOG_TIP_YELLOW));
        dialog->setMessage(tr("Are you sure you want to remove it from the whitelist?"));
        dialog->setWordWrapMessage(true);

        // 针对DTK弹窗目前accessibleName会随系统语言变化的情况
        // 通过insertButton的形式定制按钮,保持accessiableName的一致性
        QPushButton *cancelBtn = new QPushButton(dialog);
        cancelBtn->setText(tr("Cancel", "button"));
        cancelBtn->setObjectName("cancelBtn");
        SET_ACC_NAME(cancelBtn, RemoveWhitelistDialog_cancelButton);
        cancelBtn->setAttribute(Qt::WA_NoMousePropagation);
        dialog->insertButton(0, cancelBtn, false);

        QPushButton *exitBtn = new QPushButton(dialog);
        exitBtn->setText(tr("Confirm", "button"));
        exitBtn->setObjectName("confirmBtn");
        SET_ACC_NAME(exitBtn, RemoveWhitelistDialog_confirmButton);
        exitBtn->setAttribute(Qt::WA_NoMousePropagation);
        dialog->insertButton(1, exitBtn, true);

        QLabel *messageLable = dialog->findChild<QLabel *>("MessageLabel");
        SET_ACC_NAME(messageLable, RemoveWhitelistDialog_messageLable);

        connect(dialog, SIGNAL(buttonClicked(int, const QString & )), this, SLOT(onWhitelistStrategyChangedHelp(int, const QString & )));
        dialog->show();
    }
    // 白名单添加：弹出密码认证框
    if (type == USB_MANAGER_OP_TYPE_ADD) {
        // 如果设备信息不全
        if (info.serial.isEmpty() || info.vendorID.isEmpty() || info.productID.isEmpty()) {
            qDebug() << Q_FUNC_INFO << info.name << info.size << "'s info is not invalid!";

            DDialog dlg;
            dlg.setMinimumWidth(450);
            dlg.setMaximumWidth(500);
            dlg.setIcon(QIcon::fromTheme(DIALOG_TIP_RED));
            dlg.setMessage(tr("Failed to add to the whitelist: incomplete device info. Please contact the USB device supplier for help."));
            dlg.addButton(tr("Confirm", "button"), true);

//            connect(qApp, SIGNAL(fontChanged()), this, [&dlg] {
//                dlg.window()->adjustSize();
//            });
            dlg.exec();

            return;
        }

        // 授权弹窗前，禁用所有控件
        enableAllWidgets(false);
        // 身份验证
        Q_EMIT m_usbStorageSecurityModel->sendRequestConfirmAddUsbConnectionWhiteLst(info);
    }
}

// 完成信号->移除白名单
void USBStorageSecurityWidget::removeWhitelist(const USBConnectionInfo &info)
{
    for (int i = m_connectionRecordTableModel->rowCount() - 1; i >= 0; i--) {
        if (info.serial == m_connectionRecordTableModel->index(i, USB_LOG_ITEM_DATA_COL).data(DATA_ROLE_SERIAL).toString()
            && info.productID == m_connectionRecordTableModel->index(i, USB_LOG_ITEM_DATA_COL).data(DATA_ROLE_PRODUCT_ID).toString()
            && info.vendorID == m_connectionRecordTableModel->index(i, USB_LOG_ITEM_DATA_COL).data(DATA_ROLE_VENDOR_ID).toString()) {
            m_connectionRecordTableModel->dataResetBegin();
            m_connectionRecordTableModel->setData(m_connectionRecordTableModel->index(i, USB_LOG_ITEM_DATA_COL), USB_NOT_ON_WHITELIST, DATA_ROLE_OP_STATUS);
            m_connectionRecordTableModel->dataResetEnd();
        }
    }
}

// 完成信号->添加到白名单
void USBStorageSecurityWidget::addWhitelist(const USBConnectionInfo &info)
{
    for (int i = m_connectionRecordTableModel->rowCount() - 1; i >= 0; i--) {
        if (info.serial == m_connectionRecordTableModel->index(i, USB_LOG_ITEM_DATA_COL).data(DATA_ROLE_SERIAL).toString()
            && info.productID == m_connectionRecordTableModel->index(i, USB_LOG_ITEM_DATA_COL).data(DATA_ROLE_PRODUCT_ID).toString()
            && info.vendorID == m_connectionRecordTableModel->index(i, USB_LOG_ITEM_DATA_COL).data(DATA_ROLE_VENDOR_ID).toString()) {
            m_connectionRecordTableModel->dataResetBegin();
            m_connectionRecordTableModel->setData(m_connectionRecordTableModel->index(i, USB_LOG_ITEM_DATA_COL), USB_ON_WHITELIST, DATA_ROLE_OP_STATUS);
            m_connectionRecordTableModel->dataResetEnd();
        }
    }
}

void USBStorageSecurityWidget::showAddWhitelistTip()
{
    DDialog dlg(this);
    dlg.setAccessibleName("addWhitelistTip");
    dlg.setModal(true);
    dlg.setOnButtonClickedClose(true);
    // 设置左上角图标
    dlg.setIcon(QIcon::fromTheme(DIALOG_TIP_YELLOW));
    dlg.setMessage(tr("Added to the whitelist successfully, please reinsert the device to make changes take effect"));
    dlg.setMaximumWidth(400);
    dlg.setWordWrapMessage(true);
    dlg.addButton(tr("OK", "button"), true);
    dlg.exec();
}

// 导出全部设备 全部连接记录信息
void USBStorageSecurityWidget::exportAllRecords()
{
    // 向DBUS请求数据，然后得到Dbus 导出的完成信号，将数据存到相应的路径下

    // 当前时间戳
    QString currentTime = QDateTime::currentDateTime().toString("yyyyMMddhhmmss");

    QString savePath = QFileDialog::getSaveFileName(this, tr("Save to"), QDir::homePath() + "/Desktop/" + tr("USB Connections_%1.csv").arg(currentTime), "*.csv");

    if (savePath.isEmpty()) {
        qDebug() << Q_FUNC_INFO << "export canceled!";
        return;
    }

    // 导出全部 USB设备全部连接记录  导出功能
    m_usbStorageSecurityModel->asyncGetAllUSBStorageConnList(savePath);
}

void USBStorageSecurityWidget::matchConetentBySearch(const QString &text)
{
    // 待匹配的字符串 (不区分大小写)
    const QString matchText = text.toLower(); // 转换为小写
    USBConnectionInfoList matchedUSBInfoList;
    // 获取USB连接记录表格显示的数据
    const USBConnectionInfoList USBConnInfoList = m_usbStorageSecurityModel->usbConnectionInfoLst();
    // 遍历匹配
    for (int i = 0; i < USBConnInfoList.size(); ++i) {
        const USBConnectionInfo infoTmp = USBConnInfoList.at(i);
        // 名称匹配
        QString name = infoTmp.name;
        if (name.isEmpty()) {
            // 取大小作为名称
            const QString &formatedName = QString("%1 ").arg(Utils::formatBytes(infoTmp.size, 1));
            name = QString(tr("%1 Volume")).arg(formatedName);
        }
        // 统一以小写进行匹配
       const QString nameLowerStr = name.toLower();

        // 名称对应无声调拼音
        PinyinInfo pinYininfo = Utils::getPinYinInfoFromStr(nameLowerStr);
        if (pinYininfo.noTonePinYin.contains(matchText)) {
            matchedUSBInfoList.append(infoTmp);
            continue;
        }

        // 匹配名称(拼音首字母缩写)
        if (pinYininfo.simpliyiedPinYin.contains(matchText)) {
            matchedUSBInfoList.append(infoTmp);
            continue;
        }

        // 匹配名称(不区分大小写)
        if (nameLowerStr.contains(matchText)) {
            matchedUSBInfoList.append(infoTmp);
            continue;
        }

        // PID 匹配
        if (infoTmp.productID.toLower().contains(matchText)) {
            matchedUSBInfoList.append(infoTmp);
            continue;
        }

        // VID 匹配
        if (infoTmp.vendorID.toLower().contains(matchText)) {
            matchedUSBInfoList.append(infoTmp);
            continue;
        }

        // SN 匹配
        if (infoTmp.serial.toLower().contains(matchText)) {
            matchedUSBInfoList.append(infoTmp);
            continue;
        }
    }

    // 重新加载 USB连接记录列表
    reloadUSBConnList(matchedUSBInfoList);

    // 判断是否需要显示无搜索结果提示
    m_needShowNoSearchResultTip = matchedUSBInfoList.isEmpty() ? true : false;

    // 更新UI 显示
    updateUI();
}

void USBStorageSecurityWidget::updateUIStatus()
{
    // 刷新状态
    setEnabled(m_usbStorageSecurityModel->getUIEnableStatus());
}

void USBStorageSecurityWidget::enableAllWidgetsTrue()
{
    this->enableAllWidgets(true);
}

void USBStorageSecurityWidget::confirmClearUsbConnectionLogHelp(int index, QString)
{
    switch (index) {
    case 0:
        break;
    case 1:
        // 授权弹窗前，禁用所有控件
        enableAllWidgets(false);
        // 请求确认清除usb连接记录
        Q_EMIT m_usbStorageSecurityModel->sendRequestConfirmClearUsbConnectionLog();
        break;
    default:
        break;
    }
}

void USBStorageSecurityWidget::selectLimitationModelHelp(int index, QString)
{
    switch (index) {
    case 0:
        updateUsbLimitModeItem();
        break;
    case 1:
        // 状态修改，同步到work
        m_usbStorageSecurityModel->asyncSelectLimitationMode(LIMIT_MODE_NO_INDEX);
        break;
    default:
        updateUsbLimitModeItem();
        break;
    }
}

void USBStorageSecurityWidget::onWhitelistStrategyChangedHelp(int index, const QString &)
{
    switch (index) {
    case 0:
        break;
    case 1:
        // 对USB白名单 进行设置  增删改
        m_usbStorageSecurityModel->asyncOperateStorageWhitelist(gType, gInfo);
        break;
    default:
        break;
    }
}

QHBoxLayout *USBStorageSecurityWidget::initTable()
{
    QHBoxLayout *mainLayout = new QHBoxLayout;
    m_connectionRecordTableWgt = initConnectionRecordTableWgt();
    SET_ACC_NAME(m_connectionRecordTableWgt, connectionRecordWidget);
    mainLayout->addWidget(m_connectionRecordTableWgt);

    return mainLayout;
}

void USBStorageSecurityWidget::initConnect()
{
    connect(m_usbStorageSecurityModel, SIGNAL(sendNeedShowRecords(const USBConnectionInfoList &)), this, SLOT(onRecvNeedShowRecords(const USBConnectionInfoList &)));
    connect(m_usbStorageSecurityModel, SIGNAL(sendUsbConnectionLogInfo(const USBConnectionInfo &)), this, SLOT(onReceiveUsbInfo(const USBConnectionInfo &)));
    // usb限制模式按钮信号
    connect(m_usbLimitModeMenu, SIGNAL(triggered(QAction *)), this, SLOT(selectLimitationModel(QAction *)));
    // 通知去改变usb限制模式
    connect(m_usbStorageSecurityModel, SIGNAL(notifyChangeLimitationMode(int)), this, SLOT(updateUsbLimitModeItem()));

    // 白名单弹窗按钮
    connect(m_whiteListBtn, SIGNAL(clicked()), this, SLOT(onOpenWhitelist()));

    // 权限校验完成
    connect(m_usbStorageSecurityModel, SIGNAL(checkAuthorizationFinished()), this, SLOT(enableAllWidgetsTrue()));

    // 连接清除记录按钮信号
    connect(m_clearLogBtn, SIGNAL(clicked()), this, SLOT(confirmClearUsbConnectionLog()));

    // 清除USB连接记录完成，改变界面
    connect(m_usbStorageSecurityModel, SIGNAL(clearAllDevRecordsFinished()), this, SLOT(clearAllDevRecords()));

    // 点击详情页图标显示详情页
    connect(m_USBRecordsDelegate, SIGNAL(sendShowUSBDetails(USBConnectionInfo )), this, SLOT(onShowDetailsDlg(USBConnectionInfo )));

    // 代理信号  增删白名单操作
    connect(m_USBRecordsDelegate, SIGNAL(sendOperateWhitelist(int, const USBConnectionInfo &)), this, SLOT(onWhitelistStrategyChanged(int, const USBConnectionInfo &)));

    // 通过图标点击，添加到白名单，刷新delegate显示
    connect(m_usbStorageSecurityModel, SIGNAL(addUSBWhitelistFinished(const USBConnectionInfo &)), this, SLOT(addWhitelist(const USBConnectionInfo &)));

    // 通过图标点击，从白名单中移除，刷新delegate显示
    connect(m_usbStorageSecurityModel, SIGNAL(removeWhitelistFinished(const USBConnectionInfo &)), this, SLOT(removeWhitelist(const USBConnectionInfo &)));

    // 通过图标点击，添加到白名单后,Show 提示弹窗
    connect(m_usbStorageSecurityModel, SIGNAL(notifyShowAddWhitelistTip()), this, SLOT(showAddWhitelistTip()));

    // 导出USB全部连接信息
    connect(m_exportBtn, SIGNAL(clicked()), this, SLOT(exportAllRecords()));

    // 搜索框
    connect(m_searchEdit, SIGNAL(textChanged(const QString &)), this, SLOT(matchConetentBySearch(const QString &)));

    // 连接记录界面是否启用状态刷新
    connect(m_usbStorageSecurityModel, SIGNAL(notifyWhitelistDlgUpdate()), this, SLOT(updateUIStatus()));
}

QWidget *USBStorageSecurityWidget::initConnectionRecordTableWgt()
{
    QFrame *mainWgt = new QFrame(this);
    QVBoxLayout *mainLayout = new QVBoxLayout;
    mainLayout->setContentsMargins(0, 0, 0, 6);
    mainWgt->setLayout(mainLayout);

    m_connectionRecordTable = new QTableView(this);
    SET_ACC_NAME(m_connectionRecordTable, tableView);

    // 设置代理
    m_USBRecordsDelegate = new USBRecordsDelegate(this);
    m_connectionRecordTable->setItemDelegate(m_USBRecordsDelegate);

    // 设置表格行标题
    m_connectionRecordTable->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_connectionRecordTable->setSelectionMode(QAbstractItemView::NoSelection);
    m_connectionRecordTable->setEditTriggers(QAbstractItemView::NoEditTriggers);
    m_connectionRecordTable->setFrameShape(QTableView::NoFrame);
    m_connectionRecordTable->setIconSize(QSize(16, 16));
    // 自动调整最后一列的宽度使它和表格的右边界对齐
    m_connectionRecordTable->horizontalHeader()->setStretchLastSection(true);
    m_connectionRecordTable->verticalHeader()->setHidden(true);
    m_connectionRecordTable->setShowGrid(false);
    m_connectionRecordTable->verticalHeader()->setDefaultSectionSize(36);

    // 初始化表头
    m_headerDelegate = new DefenderTableHeaderView(Qt::Horizontal, this);
    // 表头行高设置
    m_headerDelegate->setFixedHeight(36);
    // 设置更换表头
    m_connectionRecordTable->setHorizontalHeader(m_headerDelegate);

    // 设置表头
    QStandardItem *standaritem0 = new QStandardItem(tr("Device"));
    standaritem0->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    QStandardItem *standaritem1 = new QStandardItem(tr("Time Connected"));
    standaritem1->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    QStandardItem *standaritem2 = new QStandardItem(tr("Policy"));
    standaritem2->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);
    QStandardItem *standaritem3 = new QStandardItem(tr("Action"));
    standaritem3->setTextAlignment(Qt::AlignLeft | Qt::AlignVCenter);

    m_connectionRecordTableModel = new USBStorageItemRefreshModel(this);
    m_connectionRecordTableModel->setHorizontalHeaderItem(USB_LOG_ITEM_NAME_COL, standaritem0);
    m_connectionRecordTableModel->setHorizontalHeaderItem(USB_LOG_ITEM_TIME_COL, standaritem1);
    m_connectionRecordTableModel->setHorizontalHeaderItem(USB_LOG_ITEM_STATUS_COL, standaritem2);
    m_connectionRecordTableModel->setHorizontalHeaderItem(USB_LOG_ITEM_BTN_COL, standaritem3);
    m_connectionRecordTableModel->horizontalHeaderItem(USB_LOG_ITEM_BTN_COL)->setSelectable(false);
    m_connectionRecordTableModel->setRowCount(0);

    // 设置数据
    m_connectionRecordTable->setModel(m_connectionRecordTableModel);

    // 屏蔽排序/表头排序图标
    m_connectionRecordTable->setSortingEnabled(false);
    m_connectionRecordTable->horizontalHeader()->setSortIndicatorShown(false);

    mainLayout->addWidget(m_connectionRecordTable);

    //设置usb连接记录表格内容
    QList<USBConnectionInfo> usbConnectionInfoLst = m_usbStorageSecurityModel->usbConnectionInfoLst();

    for (int i = 0; i < usbConnectionInfoLst.size(); i++) {
        USBConnectionInfo info = usbConnectionInfoLst.at(i);
        appendUsbConnectionLog(info);
    }

    //不显示 数据 栏
    m_connectionRecordTable->setColumnHidden(USB_LOG_ITEM_DATA_COL, true);

    //设置各栏宽度
    m_connectionRecordTable->setColumnWidth(USB_LOG_ITEM_NAME_COL, 210);
    m_connectionRecordTable->setColumnWidth(USB_LOG_ITEM_TIME_COL, 190);
    m_connectionRecordTable->setColumnWidth(USB_LOG_ITEM_STATUS_COL, 150);

    //默认排序 -- 时间排序
    m_connectionRecordTable->sortByColumn(USB_LOG_ITEM_TIME_COL, Qt::SortOrder::DescendingOrder);

    return mainWgt;
}

void USBStorageSecurityWidget::appendUsbConnectionLog(USBConnectionInfo info)
{
    // 数据项
    QStandardItem *dataItem = createDataItemFromInfo(info);

    QList<QStandardItem *> itemLst;
    QString deviceName = dataItem->data(DATA_ROLE_NAME).toString();
    QStandardItem *nameItem = new QStandardItem(deviceName);
    nameItem->setData(deviceName, Qt::ItemDataRole::EditRole);
    nameItem->setToolTip(nameItem->text());

    QString timeAdded = dataItem->data(DATA_ROLE_TIME).toString();
    QStandardItem *timeItem = new QStandardItem(timeAdded);
    int strategy = dataItem->data(DATA_ROLE_STRATEGY).toInt();
    QStandardItem *strategyItem = new QStandardItem;
    //设置限制状态
    if (0 == strategy) {
        strategyItem->setText(tr("Read-write")); // 读写
    } else if (1 == strategy) {
        strategyItem->setText(tr("Read only")); // 只读
    } else if (2 == strategy) {
        strategyItem->setText(tr("Block")); // 禁止
    }

    //白名单 操作栏 --遗留
    QStandardItem *btnItem = new QStandardItem;
    // 操作栏 --  添加/移除 白名单
    int operationStatus = USB_NOT_ON_WHITELIST;

    // 判断设备是否在白名单列表中
    if (m_usbStorageSecurityModel->isUsbDeviceInWhiteList(info.serial, info.vendorID, info.productID)) {
        // 设置操作栏状态
        operationStatus = USB_ON_WHITELIST;
    } else {
        operationStatus = USB_NOT_ON_WHITELIST;
    }
    dataItem->setData(operationStatus, DATA_ROLE_OP_STATUS); // 将是否在白名单列表 的标志设置到dataitem

    itemLst << nameItem << timeItem << strategyItem << btnItem << dataItem;
    m_connectionRecordTableModel->insertRow(0, itemLst);

    //为使上面加入的一行内的控件对齐
    m_connectionRecordTableModel->insertRow(0, new QStandardItem);
    m_connectionRecordTableModel->removeRow(0);

    // 设置清除记录按钮可用
    m_clearLogBtn->setDisabled(false);
}

void USBStorageSecurityWidget::confirmClearUsbConnectionLog()
{
    DDialog *dialog = new DDialog(this);
    SET_ACC_NAME(dialog, clearUsbConnDialog);
    dialog->setModal(true);
    // 设置关闭后删除
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->setIcon(QIcon::fromTheme(DIALOG_TIP_YELLOW));
    dialog->setMessage(tr("Are you sure you want to clear all the records?"));
    dialog->setWordWrapMessage(true);

    // 针对DTK弹窗目前accessibleName会随系统语言变化的情况
    // 通过insertButton的形式定制按钮,保持accessiableName的一致性
    QPushButton *cancelBtn = new QPushButton(dialog);
    cancelBtn->setText(tr("Cancel", "button"));
    cancelBtn->setObjectName("cancelBtn");
    SET_ACC_NAME(cancelBtn, clearUsbConnDialog_cancelButton);
    cancelBtn->setAttribute(Qt::WA_NoMousePropagation);
    dialog->insertButton(0, cancelBtn, false);

    QPushButton *exitBtn = new QPushButton(dialog);
    exitBtn->setText(tr("Confirm", "button"));
    exitBtn->setObjectName("confirmBtn");
    SET_ACC_NAME(exitBtn, clearUsbConnDialog_confirmButton);
    exitBtn->setAttribute(Qt::WA_NoMousePropagation);
    dialog->insertButton(1, exitBtn, true);

    QLabel *messageLable = dialog->findChild<QLabel *>("MessageLabel");
    SET_ACC_NAME(messageLable, clearUsbConnDialog_messageLable);

    connect(dialog, SIGNAL(buttonClicked(int, QString)), this, SLOT(confirmClearUsbConnectionLogHelp(int, QString)));
    dialog->show();
}

// 清除所有界面 连接记录
void USBStorageSecurityWidget::clearAllDevRecords()
{
    //清除表格数据
    int count = m_connectionRecordTableModel->rowCount();
    for (int i = 0; i < count; i++) {
        m_connectionRecordTableModel->removeRow(0);
    }

    // 设置清除记录按钮不可用
    m_clearLogBtn->setDisabled(true);
}

void USBStorageSecurityWidget::updateUsbLimitModeItem()
{
    // 获取当前限制模式
    int mode = m_usbStorageSecurityModel->getGlobalPermMode();

    int checkedActionIndex = LIMIT_MODE_RW_INDEX;
    if (USB_MANAGER_PERM_MODE_RW == mode) {
        checkedActionIndex = LIMIT_MODE_RW_INDEX;
    } else if (USB_MANAGER_PERM_MODE_RO == mode) {
        checkedActionIndex = LIMIT_MODE_RO_INDEX;
    } else if (USB_MANAGER_PERM_MODE_NO == mode) {
        checkedActionIndex = LIMIT_MODE_NO_INDEX;
    }
    for (QAction *ttaction : m_usbLimitModeItem->button()->menu()->actions()) {
        ttaction->setChecked(false);
    }
    QAction *checkedAction = m_usbLimitModeItem->button()->menu()->actions().at(checkedActionIndex);
    checkedAction->setChecked(true);
    m_usbLimitModeItemButtonLabel->setText(checkedAction->text());
}

void USBStorageSecurityWidget::cleanUsbConnectionLog()
{
    QDateTime limitTime = QDateTime::currentDateTime().addDays(-30);
    for (int i = 0; i < m_connectionRecordTableModel->rowCount(); i++) {
        QString datetime = m_connectionRecordTableModel->item(i, USB_LOG_ITEM_DATA_COL)->data(DATA_ROLE_TIME).toString();
        QDateTime itemTime = QDateTime::fromString(datetime, USB_MANAGER_CONN_TIME_FORMATION);
        //清除超过30天记录项
        if (limitTime > itemTime) {
            m_connectionRecordTableModel->removeRow(i);
            i--;
        }
    }
}

// 通过usb连接信息获得数据项
QStandardItem *USBStorageSecurityWidget::createDataItemFromInfo(const USBConnectionInfo &info)
{
    // 数据项
    QStandardItem *dataItem = new QStandardItem;

    // 设备名
    QString deviceName;
    if (info.name.isEmpty()) {
        const QString &formatedName = QString("%1 ").arg(Utils::formatBytes(info.size, 1));
        deviceName = QString(tr("%1 Volume")).arg(formatedName);
    } else {
        deviceName = info.name;
    }
    dataItem->setData(deviceName, DATA_ROLE_NAME);

    // 添加时间
    dataItem->setData(info.addedTime, DATA_ROLE_TIME);
    // 连接状态
    dataItem->setData(info.permMode, DATA_ROLE_STRATEGY);
    // 序列号
    dataItem->setData(info.serial, DATA_ROLE_SERIAL);
    // 经销商id
    dataItem->setData(info.vendorID, DATA_ROLE_VENDOR_ID);
    // 制造商id
    dataItem->setData(info.productID, DATA_ROLE_PRODUCT_ID);
    // 添加/移除白名单状态
    dataItem->setData(USB_NOT_ON_WHITELIST, DATA_ROLE_OP_STATUS);

    return dataItem;
}

void USBStorageSecurityWidget::enableAllWidgets(bool enable)
{
    // 找到主窗口并置灰
    for (QWidget *widget : QApplication::allWidgets()) {
        if (MAIN_WINDOW_OBJ_NAME == widget->objectName()) {
            widget->setEnabled(enable);
        }
    }
}

// 重新加载USB 连接记录列表
void USBStorageSecurityWidget::reloadUSBConnList(const USBConnectionInfoList &list)
{
    // 清空列表内容
    for (int i = m_connectionRecordTableModel->rowCount() - 1; i >= 0; --i) {
        m_connectionRecordTableModel->removeRow(i);
    }

    // 排序插入数据
    for (int i = 0; i < list.size(); i++) {
        USBConnectionInfo info = list.at(i);
        appendUsbConnectionLog(info);
    }
    // 根据表格内容是否为空，设置清除记录按钮是否可用
    if (0 == m_connectionRecordTableModel->rowCount()) {
        m_clearLogBtn->setDisabled(true);
    } else {
        m_clearLogBtn->setDisabled(false);
    }
}

void USBStorageSecurityWidget::updateUI()
{
    if (m_needShowNoSearchResultTip) {
        m_blankTip->setText(tr("No search results"));
    }

    // 无策略是文字区域
    if (m_connectionRecordTableModel->rowCount()) {
        m_blankArea->hide();
        m_connectionRecordTableWgt->show();
        m_connectionRecordTable->show();
    } else {
        m_blankArea->show();
        m_connectionRecordTableWgt->hide();
        m_connectionRecordTable->hide();
    }
}

void USBStorageSecurityWidget::selectLimitationModel(QAction *action)
{
    action->setChecked(true);
    int mode = m_usbStorageSecurityModel->getGlobalPermMode(); // 当前选择模式

    if (ALLOW_RW_NAME == action->objectName()) {
        // 如果再次选择相同项，则不做处理
        if (USB_MANAGER_PERM_MODE_RW == mode)
            return;
        // 授权弹窗前，禁用所有控件
        enableAllWidgets(false);
        // 身份验证
        Q_EMIT m_usbStorageSecurityModel->sendRequestConfirmSelectLimitationMode(LIMIT_MODE_RW_INDEX);
    } else if (ALLOW_RO_NAME == action->objectName()) {
        // 如果再次选择相同项，则不做处理
        if (USB_MANAGER_PERM_MODE_RO == mode) {
            return;
        } else if (USB_MANAGER_PERM_MODE_NO == mode) {
            // 授权弹窗前，禁用所有控件
            enableAllWidgets(false);
            // 身份验证
            Q_EMIT m_usbStorageSecurityModel->sendRequestConfirmSelectLimitationMode(LIMIT_MODE_RO_INDEX);
        } else {
            m_usbStorageSecurityModel->asyncSelectLimitationMode(LIMIT_MODE_RO_INDEX);
        }
    }
    // 当选择禁止，显示提示弹窗
    else if (BLOCK_NO_NAME == action->objectName()) {
        if (USB_MANAGER_PERM_MODE_NO == mode) {
            return;
        } else {
            // 用户确认
            DDialog *dialog = new DDialog(this);
            SET_ACC_NAME(dialog, blockAllConnDialog);
            dialog->setModal(true);
            dialog->setOnButtonClickedClose(true);
            // 设置关闭后删除
            dialog->setAttribute(Qt::WA_DeleteOnClose);
            // 设置左上角图标
            dialog->setIcon(QIcon::fromTheme(DIALOG_TIP_YELLOW));
            dialog->setMessage(tr("Are you sure you want to block the connection of all USB storage devices?"));
            dialog->setWordWrapMessage(true);

            // 针对DTK弹窗目前accessibleName会随系统语言变化的情况
            // 通过insertButton的形式定制按钮,保持accessiableName的一致性
            QPushButton *cancelBtn = new QPushButton(dialog);
            cancelBtn->setText(tr("Cancel", "button"));
            cancelBtn->setObjectName("cancelBtn");
            SET_ACC_NAME(cancelBtn, blockAllConnDialog_cancelButton);
            cancelBtn->setAttribute(Qt::WA_NoMousePropagation);
            dialog->insertButton(0, cancelBtn, false);

            QPushButton *exitBtn = new QPushButton(dialog);
            exitBtn->setText(tr("Confirm", "button"));
            exitBtn->setObjectName("confirmBtn");
            SET_ACC_NAME(exitBtn, blockAllConnDialog_confirmButton);
            exitBtn->setAttribute(Qt::WA_NoMousePropagation);
            dialog->insertButton(1, exitBtn, true);

            QLabel *messageLable = dialog->findChild<QLabel *>("MessageLabel");
            SET_ACC_NAME(messageLable, blockAllConnDialog_messageLable);

            connect(dialog, SIGNAL(buttonClicked(int, QString)), this, SLOT(selectLimitationModelHelp(int, QString)));
            connect(dialog, SIGNAL(closed()), this, SLOT(updateUsbLimitModeItem()));
            dialog->show();
        }
    }

    updateUsbLimitModeItem();
}
